﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using OpenComposite.Base.Collections;
using OpenComposite.EII.Repository;

namespace OpenComposite.EII.Forms
{
	public partial class FormSelectConfigElements : Form
	{
		#region Initialization
		public FormSelectConfigElements()
		{
			InitializeComponent();

			this.DialogResult = DialogResult.Cancel;

			_elements = new List<ConfigElement>(14);
			_elements.AddRange(new ConfigElement[] {
				//new ConfigElement(false, ItemType.Business_Process, ConfigurableElement.BusinessProcesses),
				//new ConfigElement(false, ItemType.Composite, ConfigurableElement.CompositeOrchestrations),
				new ConfigElement(false, ItemType.BObject, ConfigurableElement.BusinessObjects),
				new ConfigElement(false, ItemType.BPolicy, ConfigurableElement.BusinessRules),
				//new ConfigElement(false, ItemType.BPolicy, ConfigurableElement.BusinessProcessRules),
				//new ConfigElement(false, ItemType.BPolicy, ConfigurableElement.ProcessFlowRules),
				//new ConfigElement(false, ItemType.BPolicy, ConfigurableElement.BusinessDecisionRules),
				//new ConfigElement(false, ItemType.BPolicy, ConfigurableElement.ParticipantRules),
				//new ConfigElement(false, ItemType.BPolicy, ConfigurableElement.SelectionRules),
				new ConfigElement(false, ItemType.RuleConstant, ConfigurableElement.RuleConstants),
				new ConfigElement(false, ItemType.Mapping, ConfigurableElement.SubscriptionMappings),
				new ConfigElement(false, ItemType.Mapping, ConfigurableElement.LogicalPhysicalMappings),
				new ConfigElement(false, ItemType.HumanActivity, ConfigurableElement.HumanActivityAssignments),
				new ConfigElement(false, ItemType.WebService, ConfigurableElement.WebServiceAddresses),
				new ConfigElement(false, ItemType.WebService, ConfigurableElement.WebServiceCalls)
			});

			_selectedElement = new ConfigurableElements();
			_selectedElement.ListChanged += new ListChangedEventHandler(_selectedElement_ListChanged);
		}
		#endregion

		#region Public Members

		#region Properties
		public ConfigurableElements SelectedElements
		{
			get { return _selectedElement; }
		}
		#endregion

		#region Methods
		#endregion

		#endregion

		#region Protected Members

		#region Methods
		// new
		// override
		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
		protected override void Dispose(bool disposing)
		{
			_selectedElement.ListChanged -= new ListChangedEventHandler(_selectedElement_ListChanged);

			if ( disposing && ( components != null ) ) {
				components.Dispose();
			}
			base.Dispose(disposing);
		}

		#endregion

		#endregion

		#region Private Members

		#region Fields
		private ConfigurableElements _selectedElement;
		private List<ConfigElement> _elements;
		#endregion

		#region Methods
		private void setSelectedElements()
		{
			if ( dgvElements.DataSource != _elements ) return;
			for ( int i = 0; i < _elements.Count; i++ ) {
				var item = _elements[i];
				if ( _selectedElement.Contains(item.Element) ) {
					if ( !item.Selected ) {
						item.Selected = true;
						dgvElements.UpdateCellValue(colCheck.Index, i);
					}
				} else if ( item.Selected ) {
					item.Selected = false;
					dgvElements.UpdateCellValue(colCheck.Index, i);
				}
			}
		}
		#endregion

		#region Event Handlers
		private void FormSelectConfigElements_Load(object sender, EventArgs e)
		{
			dgvElements.AutoGenerateColumns = false;
			dgvElements.DataSource = _elements;
			setSelectedElements();
		}
		private void _selectedElement_ListChanged(object sender, ListChangedEventArgs e)
		{
			setSelectedElements();
		}
		private void tsbtnOK_Click(object sender, EventArgs e)
		{
			this.DialogResult = DialogResult.OK;
			this.Close();
		}

		private void tsbtnCancel_Click(object sender, EventArgs e)
		{
			this.DialogResult = DialogResult.Cancel;
			this.Close();
		}
		private void dgvElements_CellClick(object sender, DataGridViewCellEventArgs e)
		{
			if ( e.RowIndex < 0 ) return;
			ConfigElement ce = _elements[e.RowIndex];
			if ( ce.Selected ) {
				if ( this.SelectedElements.Contains(ce.Element) ) {
					this.SelectedElements.Remove(ce.Element);
				}
			} else if ( !this.SelectedElements.Contains(ce.Element) ) {
				this.SelectedElements.Add(ce.Element);

			}
		}

		private void tsbtnSelectAll_Click(object sender, EventArgs e)
		{
			this.SelectedElements.Clear();
			foreach ( var item in _elements ) {
				item.Selected = true;
				this.SelectedElements.Add(item.Element);
			}
			dgvElements.Refresh();
		}
		private void tsbtnDeselectAll_Click(object sender, EventArgs e)
		{
			this.SelectedElements.Clear();
			foreach ( var item in _elements ) {
				item.Selected = false;
			}
			dgvElements.Refresh();
		}

		#endregion

		#endregion

	}		
	
	#region Private Class: ConfigElement
	internal class ConfigElement
	{
		public ConfigElement(bool selected, ItemType itemtype, ConfigurableElement element)
		{
			this.ItemType = itemtype;
			this.Selected = selected;
			this.Image = ItemTypes.GetImage(itemtype);
			this.Text = ConfigurableElements.GetString(element);
			this.Element = element;
		}
		public ConfigElement(bool selected, ItemType itemtype, ConfigurableElement element, string text)
			: this(selected, itemtype, element)
		{
			this.Text = text;
		}

		public bool Selected { get; set; }
		public Image Image { get; protected set; }
		public string Text { get; protected set; }
		public ItemType ItemType { get; protected set; }
		public ConfigurableElement Element { get; protected set; }
	}
	#endregion


	public class ConfigurableElements : BindingListEx<ConfigurableElement>
	{
		public override string ToString()
		{
			StringBuilder sb = new StringBuilder();
			foreach ( var item in this ) {
				if ( sb.Length > 0 ) sb.Append(", ");
				sb.Append(GetString(item));
			}
			return sb.ToString();
		}
		public static string GetString(ConfigurableElement element)
		{
			string s = "Unknown";
			object[] attrib = element.GetType().GetField(element.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
			if ( attrib != null && attrib.Length > 0 ) {
				s = ( (DescriptionAttribute)attrib[0] ).Description;
			}
			return s;
		}

		public static ConfigurableElements AllElements
		{
			get
			{
				ConfigurableElements list = new ConfigurableElements();
				list.Add(ConfigurableElement.BusinessObjects);
				list.Add(ConfigurableElement.BusinessRules);
				list.Add(ConfigurableElement.CompositeOrchestrations);
				list.Add(ConfigurableElement.HumanActivityAssignments);
				list.Add(ConfigurableElement.LogicalPhysicalMappings);
				list.Add(ConfigurableElement.RuleConstants);
				list.Add(ConfigurableElement.SubscriptionMappings);
				list.Add(ConfigurableElement.WebServiceAddresses);
				list.Add(ConfigurableElement.WebServiceCalls);
				return list;
			}
		}
	}

	public enum ConfigurableElement
	{
		[Description("None")]
		None = 0,
		[Description("Composite Orchestration")]
		CompositeOrchestrations = 1,
		[Description("Business Objects")]
		BusinessObjects = 2,
		[Description("Business Rules")]
		BusinessRules = 3,
		//[Description("Business Process Rules")]
		//BusinessProcessRules = 3,
		//[Description("Process Flow Rules")]
		//ProcessFlowRules = 4,
		//[Description("Business Decision Rules")]
		//BusinessDecisionRules = 5,
		//[Description("Participant Rules")]
		//ParticipantRules = 6,
		//[Description("Selection Rules")]
		//SelectionRules = 7,
		[Description("Rule Constants")]
		RuleConstants = 8,
		[Description("Subscription Mappings")]
		SubscriptionMappings = 9,
		[Description("Logical-Physical Mappings")]
		LogicalPhysicalMappings = 10,
		[Description("Human Activity Assignments")]
		HumanActivityAssignments = 11,
		[Description("Web Service Addresses")]
		WebServiceAddresses = 12,
		[Description("Web Service Calls")]
		WebServiceCalls = 13,
		//[Description("Business Processes")]
		//BusinessProcesses = 14
		[Description("Logical Physical Assignment")]
		LogicalPhysical = 15
	}
}
